﻿using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Input;
using BQDHelper.Models;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Win32;
using MsBox.Avalonia.Enums;
using MsBox.Avalonia;

namespace BQDHelper.ViewModels;

public partial class MainViewModel : ViewModelBase
{
    [ObservableProperty] 
    private string _greeting = "Welcome to Avalonia!";
    [ObservableProperty]
    private string _machineName = Environment.MachineName;
    [ObservableProperty]
    private string _userName = Environment.UserName;
    [ObservableProperty]
    private string _oSDescription = RuntimeInformation.OSDescription;
    [ObservableProperty] 
    private string? _macAddress = string.Empty;
    [ObservableProperty]
    private string? _iPAddress = string.Empty;
    [ObservableProperty]
    private string? _networkInterfaceName = string.Empty;
    [ObservableProperty]
    private string? _cPuType = string.Empty;
    [ObservableProperty]
    private bool _isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
    [ObservableProperty]
    private bool _isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
    [ObservableProperty]
    private bool _isOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
    private readonly string _baseDir = AppDomain.CurrentDomain.BaseDirectory;
    public ICommand OpenFileCmd { get; }
    public ICommand OpenBrowserCmd { get; }
    public ICommand InstallSoftwareBatchCmd {  get; }
    public ICommand InstallSelectSoftwareCmd { get; }
    private List<InstallItem> _installList=[];

    public List<InstallItem> InstallList
    {
        get => _installList;
        set { 
            _installList = value;
            OnPropertyChanged();
        }
    }
    public MainViewModel() 
    {
        foreach (var networkInterface in NetworkInterface.GetAllNetworkInterfaces()) 
        {
            if (networkInterface.NetworkInterfaceType == NetworkInterfaceType.Loopback || //回环接口
                networkInterface.OperationalStatus != OperationalStatus.Up|| //未启用接口
                networkInterface.Name.StartsWith("utun")|| // VPN/隧道接口
                networkInterface.Name.StartsWith("docker") )// 容器接口
                continue;
            // 网卡名称
            NetworkInterfaceName = networkInterface.Name;
            
            // 获取MAC地址
            MacAddress = BitConverter.ToString(networkInterface.GetPhysicalAddress().GetAddressBytes())
                         .Replace("-", ":");

            // 获取IPv4地址
            IPAddress = networkInterface.GetIPProperties().UnicastAddresses
                .FirstOrDefault(addr => addr.Address.AddressFamily == AddressFamily.InterNetwork)?.Address.ToString();
        }

        CPuType = GetCCpuModel();
        
        OpenFileCmd = new RelayCommand<string?>(OpenFile);
        OpenBrowserCmd = new RelayCommand<string?>(OpenBrowser);
        InstallSoftwareBatchCmd = new RelayCommand<string?>(InstallSoftwareBatch);
        InstallSelectSoftwareCmd = new AsyncRelayCommand(InstallSelectSoftware);

        if (IsWindows)
        {
            _installList.Add(new InstallItem() { Id = 1, Name = "统一扫描控件", IsSelected = false, FileName = "test.exe" });
            _installList.Add(new InstallItem() { Id = 2, Name = "信贷影像控件", IsSelected = false, FileName = "111.exe", Url = "http://www.baidu.com"});
            _installList.Add(new InstallItem() { Id = 2, Name = "信贷影像控件", IsSelected = false, FileName = "111.exe", Url = "http://www.baidu.com"});
        }
        else if (IsLinux)
        {
            _installList.Add(new InstallItem() { Id = 1, Name = "WPS", IsSelected = false, FileName = "test.deb" });
            _installList.Add(new InstallItem() { Id = 2, Name = "锐捷云坞", IsSelected = false, FileName = "111.deb", Url = "http://www.baidu.com"});
            _installList.Add(new InstallItem() { Id = 3, Name = "锐捷云坞", IsSelected = false, FileName = "111.deb", Url = "http://www.baidu.com"});
        }
        else if (IsOSX)
        {
            _installList.Add(new InstallItem() { Id = 1, Name = "WPS", IsSelected = false, FileName = "11" });
            _installList.Add(new InstallItem() { Id = 2, Name = "锐捷云坞", IsSelected = false, FileName = "11" });
        }
    }
    
    private string GetCCpuModel()
    {
        return (IsWindows, IsLinux, IsOSX) switch
        {
            (true, _, _) => GetWindowsCpuModel(),
            (_, true, _) => ExecuteBashCommandWithResult("lscpu | grep '型号名称' | sed 's/.*：\\s*//'"), //cut不支持中文字符,非麒麟系统应为Model Name
            (_, _, true) => GetMacCpuModel(), //未经测试
            _ => "Unsupported OS"
        };
    }
    private string GetWindowsCpuModel()
    {
        try
        {
            if (IsWindows)
            {
                using var key = Registry.LocalMachine.OpenSubKey(
                    @"HARDWARE\DESCRIPTION\System\CentralProcessor\0");
                return key?.GetValue("ProcessorNameString")?.ToString().Trim();
            }
        }
        catch { return "无法获取型号"; }
        return "无法获取型号";
    }
    private string ExecuteBashCommandWithResult(string command)
    {
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "/bin/bash",
                Arguments = $"-c \"{command}\"",
                RedirectStandardOutput = true
            }
        };
        process.Start();
        return process.StandardOutput.ReadToEnd().Trim();
    }

    private string GetMacCpuModel()
    {
        if (!IsOSX)
        {
            return "无法获取型号";
        }
        
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "sysctl",
                Arguments = "-n machdep.cpu.brand_string",
                RedirectStandardOutput = true
            }
        };
        process.Start();
        return process.StandardOutput.ReadToEnd().Trim();
    }

    private void OpenFile(string? fileName)
    {
        if (fileName == null)
        {
            return;
        }
        var filePath = Path.Combine(_baseDir, "Assets", "Files", fileName);
        
        if (IsWindows)
        {
            Process.Start(new ProcessStartInfo
            {
                FileName = filePath,
                UseShellExecute = true,
                CreateNoWindow = true
            });
        }
        else if (IsLinux)
        {
            Process.Start("xdg-open", filePath);
        }
        else if (IsOSX)
        {
            Process.Start("open", filePath);
        }
    }

    private void OpenBrowser(string? url)
    {
        if (url == null)
        {
            return;
        }
        if (IsWindows)
        {
            Process.Start(new ProcessStartInfo
            {
                FileName = url,
                UseShellExecute = true,
                CreateNoWindow = true
            });
        }
        else if (IsLinux)
        {
            Process.Start("xdg-open", url);
        }
        else if (IsOSX)
        {
            Process.Start("open", url);
        }
    }

    private void InstallSoftwareBatch(string? scriptName)
    {
        if (scriptName == null)
        {
            return;
        }
        var filePath = Path.Combine(_baseDir, "ExternalFiles", scriptName);
        if (IsWindows)
        {
            Process.Start(filePath);
        }
        else if (IsLinux)
        {
            var terminal = "mate-terminal";  // 麒麟默认终端
            var shellCommand = $"-x /bin/bash -c \"sh {filePath}; read -p '按任意键退出...'\"";

            Process.Start(new ProcessStartInfo
            {
                FileName = terminal,
                Arguments = shellCommand
            });
        }
        else if (IsOSX)
        {
            Process.Start("open", filePath);
        }
    }

    private async Task InstallSelectSoftware()
    {
        string filePath;
        var selectedSoftwares = InstallList.Where(x => x.IsSelected).ToList();
        foreach (var installItem in selectedSoftwares)
        {
            filePath = Path.Combine(_baseDir, "ExternalFiles", "Software", installItem.FileName);
            if (!File.Exists(filePath))
            {
                var messageBox = MessageBoxManager.GetMessageBoxStandard(
                    "错误",
                    $"{installItem.Name}所需的安装包不存在，即将跳转至下载页面",
                    ButtonEnum.Ok,
                    Icon.Warning
                );
                await messageBox.ShowAsync();
                OpenBrowser(installItem.Url);
                continue;
            }

            try
            {
                await Task.Run(async () => { 
                    var process = IsWindows ? Process.Start(filePath) :
                        IsLinux ? Process.Start("kylin-installer", filePath) :
                        Process.Start("open", filePath);
            
                    await process.WaitForExitAsync();
                        
                });
            }
            catch (Exception)
            {
                var messageBox = MessageBoxManager.GetMessageBoxStandard(
                    "错误",
                    $"{installItem.Name}在安装过程出现意外，请确认情况后联系管理员",
                    ButtonEnum.Ok,
                    Icon.Error
                );
                await messageBox.ShowAsync();
            }
        }

        
    }
}
